package com.kordar.auth;

import com.kordar.rbac.AuthManager;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableConfigurationProperties(AuthProperties.class)
@ConditionalOnProperty(prefix = "kordar.auth", name = "active", havingValue = "true")
public class AuthConfig {

    final
    AuthManager authManager;

    final
    AuthProperties authProperties;

    public AuthConfig(AuthManager authManager, AuthProperties authProperties) {
        this.authManager = authManager;
        this.authProperties = authProperties;
    }

    @Bean
    public AuthService authService() {
        AuthServiceImpl authService = new AuthServiceImpl();
        authService.setAuthManager(authManager);
        return authService;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        Map<String, Filter> map = new HashMap<>();
        AuthFilter authFilter = new AuthFilter();
        authFilter.setAuthService(authService());
        map.put("rbac", authFilter);
        shiroFilterFactoryBean.setFilters(map);
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        shiroFilterFactoryBean.setLoginUrl(authProperties.getLoginUrl());
        shiroFilterFactoryBean.setUnauthorizedUrl(authProperties.getUnauthorizedUrl());
        shiroFilterFactoryBean.setSuccessUrl(authProperties.getSuccessUrl());
        Map<String, String> filterChainDefinitionMap = new HashMap<>();
        // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        authProperties.getFilterChain().forEach(filterChainDefinitionMap::put);
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    // 权限管理，配置主要是Realm的管理认证
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(customRealm());
        return securityManager;
    }

    @Bean
    public CustomRealm customRealm() {
        CustomRealm realm = new CustomRealm();
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("md5");
        matcher.setHashIterations(1);
        realm.setCredentialsMatcher(matcher);
        realm.setAuthService(authService());
        return realm;
    }
}
